package org.alvin.splitfile;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.math.BigDecimal;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 大文件拆分和合并
 */
public class SplitAndMergeFile {

    public static SplitFile splitFile(String path, int itemSize) throws IOException {
        Path filePath = Paths.get(path);
        long length = Files.size(filePath);
        if (itemSize >= length) {
            SplitFile splitFile = new SplitFile();
            splitFile.setPath(path);
            splitFile.setSize(length);

            List<SplitItem> itemList = new ArrayList<>();
            SplitItem item = new SplitItem();
            item.setLength((int) length);
            item.setIndex(1);
            item.setPath(path);
            item.setBuff(Files.readAllBytes(filePath));
            itemList.add(item);

            splitFile.setItemList(itemList);
            return splitFile;
        }
        SplitFile splitFile = new SplitFile();
        splitFile.setPath(path);
        splitFile.setSize(length);

        List<SplitItem> itemList = new ArrayList<>();
        try (RandomAccessFile randomAccessFile = new RandomAccessFile(path, "r")) {
            int fileCount = BigDecimal.valueOf(length).divide(BigDecimal.valueOf(itemSize), 0, BigDecimal.ROUND_UP).intValue();
            int offset = 0;
            for (int i = 0; i < fileCount; i++) {
                byte[] buff = new byte[itemSize];
                randomAccessFile.seek(offset);
                int itemLength = randomAccessFile.read(buff);
                //
                SplitItem item = new SplitItem();
                item.setIndex(i);
                item.setPath(path + "_" + i);
                item.setLength(itemLength);
                //
                byte[] content = new byte[itemLength];
                System.arraycopy(buff, 0, content, 0, content.length);
                item.setBuff(content);
                itemList.add(item);
                //
                offset += itemLength;
            }
        }
        splitFile.setItemList(itemList);
        return splitFile;
    }

    public static void mergeFile(String path, List<byte[]> buffs) throws IOException {
        try (RandomAccessFile randomAccessFile = new RandomAccessFile(path, "rw")) {
            int offset = 0 ;
            for (byte[] buff : buffs) {
                randomAccessFile.write(buff);
                offset+= buff.length;
                randomAccessFile.seek(offset);
            }
        }
    }



}
